﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// 用于显示当前敌人波次计时的组件
/// 功能：根据预设的波次时间间隔，显示剩余时间进度条、当前波次和总波次数，触发波次开始事件
/// </summary>
[RequireComponent(typeof(Image))] // 确保组件附加在包含 Image 组件的 GameObject 上
public class WavesTimer : MonoBehaviour
{
    // 剩余时间进度条（通过 Image.fillAmount 显示进度）
    public Image timeBar;
    // 显示当前波次的文本组件（如“当前波次：1”）
    public Text currentWaveText;
    // 显示总波次数的文本组件（如“总波次：5”）
    public Text maxWaveNumberText;
    // 波次开始时的高亮特效对象（如闪烁动画）
    public GameObject highlightedFX;
    // 高亮特效的持续时间（单位：秒）
    public float highlightedTO = 0.2f;
    // 波次信息配置对象（存储各波次的时间间隔）
    private WavesInfo wavesInfo;
    // 波次时间间隔列表（从 WavesInfo 中获取，单位：秒）
    private List<float> waves = new List<float>();
    // 当前处理的波次索引（从 0 开始计数）
    private int currentWave;
    // 当前波次的剩余时间（单位：秒）
    private float currentTimeout;
    // 时间计数器（用于递减计算剩余时间）
    private float counter;
    // 计时是否结束（所有波次已生成）
    private bool finished;

    /// <summary>
    /// 当组件禁用时触发（如场景切换、对象销毁）
    /// 功能：停止所有协程，避免无效计时
    /// </summary>
    void OnDisable()
    {
        StopAllCoroutines(); // 停止所有正在运行的协程
    }

    /// <summary>
    /// 初始化阶段调用（在 Start 之前执行）
    /// 功能：获取波次配置信息，校验 UI 组件是否存在
    /// </summary>
    void Awake()
    {
        // 获取场景中的 WavesInfo 组件（用于读取波次时间配置）
        wavesInfo = FindObjectOfType<WavesInfo>();
        // 断言校验：确保所有 UI 组件和配置对象已正确赋值
        Debug.Assert(
            timeBar && highlightedFX && wavesInfo && currentWaveText && maxWaveNumberText,
            "Wrong initial settings"
        );
    }

    /// <summary>
    /// 组件启用时调用（仅执行一次）
    /// 功能：初始化波次显示，隐藏高亮特效，设置总波次数
    /// </summary>
    void Start()
    {
        highlightedFX.SetActive(false); // 初始时隐藏高亮特效
        waves = wavesInfo.wavesTimeouts; // 获取波次时间间隔列表
        currentWave = 0; // 从第 0 波次开始（实际显示时可能+1，需看业务逻辑）
        counter = 0f; // 时间计数器清零
        finished = false; // 计时未结束
        GetCurrentWaveCounter(); // 初始化当前波次的剩余时间
        maxWaveNumberText.text = waves.Count.ToString(); // 显示总波次数（列表长度即为总波次）
        currentWaveText.text = "0"; // 初始显示当前波次为 0（可能对应实际第 1 波次，需看逻辑）
    }

    /// <summary>
    /// 固定帧率更新（每秒执行约 50 次，适用于物理计算或计时）
    /// 功能：处理波次计时逻辑，更新进度条和波次显示，触发波次开始事件
    /// </summary>
    void FixedUpdate()
    {
        if (!finished) // 若计时未结束
        {
            // 时间计数器递减至 0 时，触发波次开始
            if (counter <= 0f)
            {
                // 触发“WaveStart”事件，通知游戏开始生成当前波次的敌人
                EventManager.TriggerEvent("WaveStart", null, currentWave.ToString());
                currentWave++; // 切换到下一波次
                currentWaveText.text = currentWave.ToString(); // 更新当前波次显示

                // 播放波次开始的高亮特效
                StartCoroutine("HighlightTimer");

                // 检查是否所有波次已处理完毕
                if (!GetCurrentWaveCounter()) // 获取下一波次的剩余时间，若返回 false 表示无更多波次
                {
                    finished = true; // 标记计时结束
                    // 触发“TimerEnd”事件，通知游戏波次生成完毕
                    EventManager.TriggerEvent("TimerEnd", null, null);
                    return; // 退出更新，避免无效计算
                }
            }

            // 递减时间计数器（使用固定时间间隔，确保计时稳定）
            counter -= Time.fixedDeltaTime;
            // 更新进度条显示（剩余时间 / 总时间）
            if (currentTimeout > 0f)
            {
                timeBar.fillAmount = counter / currentTimeout; // 计算进度比例
            }
            else
            {
                timeBar.fillAmount = 0f; // 避免除数为零，进度条置零
            }
        }
    }

    /// <summary>
    /// 获取当前波次的剩余时间
    /// 返回值：是否成功获取有效时间（即是否存在未处理的波次）
    /// </summary>
    private bool GetCurrentWaveCounter()
    {
        bool res = false;
        // 检查当前波次索引是否在波次列表范围内
        if (waves.Count > currentWave)
        {
            counter = currentTimeout = waves[currentWave]; // 设置剩余时间和总时间
            res = true; // 返回成功
        }
        return res;
    }

    /// <summary>
    /// 高亮特效的协程方法
    /// 功能：显示高亮特效并在指定时间后隐藏
    /// </summary>
    private IEnumerator HighlightTimer()
    {
        highlightedFX.SetActive(true); // 显示高亮特效
        yield return new WaitForSeconds(highlightedTO); // 等待指定时间
        highlightedFX.SetActive(false); // 隐藏高亮特效
    }

    /// <summary>
    /// 当组件被销毁时触发
    /// 功能：停止所有协程，避免内存泄漏
    /// </summary>
    void OnDestroy()
    {
        StopAllCoroutines(); // 停止所有正在运行的协程
    }
}